#pragma once
#include <atomic>
#include <thread>
#include <functional>
#include <vector>
#include <opencv2/opencv.hpp>
#include "decoder/common/thread_safe_queue.hpp"

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
namespace WD {
struct FrameWithTimestamp {
    cv::Mat image;
    double timestamp;
    int camera_id = -1;
};

class StreamDecoderWorker {
public:
    StreamDecoderWorker(int stream_index,
                        AVFormatContext* fmt_ctx,
                        AVCodecParameters* codecpar,
                        std::shared_ptr<ThreadSafeQueue<AVPacket*>> pkt_queue,
                        std::function<void(const FrameWithTimestamp&)> frame_cb);
    ~StreamDecoderWorker();

    void start();
    void stop();

private:
    void decodeLoop();

    int stream_index_;
    AVFormatContext* fmt_ctx_;
    AVCodecContext* codec_ctx_ = nullptr;
    SwsContext* sws_ctx_ = nullptr;

    std::atomic<bool> running_{false};
    std::thread thread_;
    std::shared_ptr<ThreadSafeQueue<AVPacket*>> pkt_queue_;
    std::function<void(const FrameWithTimestamp&)> frame_cb_;

    int width_ = 0;
    int height_ = 0;
    std::vector<uint8_t> rgb_buffer_;
};
} // namespace WD
